package com.t.bricks.bussiness.service.sourcemanage.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.t.bricks.bussiness.model.sourcemanage.ExplorerInfo;
import com.t.bricks.bussiness.model.sourcemanage.FileInfo;
import com.t.bricks.bussiness.model.sourcemanage.FolderInfo;
import com.t.bricks.bussiness.service.sourcemanage.SourceManageService;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.function.date.TimeUtil;
import com.t.bricks.utils.function.file.FileUtil;
import com.t.bricks.utils.function.json.JacksonShell;

/**
 * 资源管理服务接口实现
 * @author HuangXinBian
 * @DateTime 2022年2月14日 上午11:49:16
 */
@Service
public class SourceManageServiceImpl implements SourceManageService {

	/**
	 * 目标资源根目录
	 */
	@Value("${app.target.root.dir}")
	private String targetRootDir;
	
	//---------------------------- 创建目录内的文件信息 开始 -------------------------//
	
	/**
	 * 创建目录内的文件信息
	 * @param dir
	 * @return
	 */
	@Override
	public MsgEmity createInfo(String dir) {
		if (null == dir || "".equals(dir)) {
			return MsgEmity.err(8001, "目录参数为空");
		}
		
		dir = String.format("%s/%s", targetRootDir, dir);
		File file = new File(dir);
		if (!file.exists()) {
			return MsgEmity.err(8002, "目录不存在.注意:目录只能是相对路径");
		}
		
		searchDir(dir, true);
		
		return MsgEmity.success("执行成功");
	}
	
	/**
	 * 创建目录内的文件信息
	 * @param dir
	 * @param isRecursion 是否递归
	 * @return
	 */
	private MsgEmity searchDir(String dir, boolean isRecursion) {
		File folder = new File(dir);
		if (!folder.exists()) {
			return MsgEmity.err(8011, "目录不存在");
		}
		
		if (!folder.isDirectory()) {
			return MsgEmity.err(8012, "指定目录参数不是一个正确目录");
		}
		
		FolderInfo folderInfo = new FolderInfo();
		folderInfo.setsName(folder.getName());
		folderInfo.setsPath(folder.getPath().replaceAll("\\\\", "/").replace(targetRootDir, ""));
		folderInfo.setsTime(TimeUtil.toStr(folder.lastModified()));
		
		List<FileInfo> list = new ArrayList<>(folder.list().length);
		for (File file : folder.listFiles()) {
			if (file.isDirectory() && isRecursion) {
				MsgEmity me = searchDir(file.getPath(), isRecursion);
				FolderInfo childFolderInfo = me.getData();
				if (null != folderInfo && null != folderInfo.getFileInfos() && folderInfo.getFileInfos().size() > 0) {
					if (null == folderInfo.getChilds()) {
						folderInfo.setChilds(new ArrayList<>());
					}
					
					folderInfo.getChilds().add(childFolderInfo);
				}
				
				continue;
			}
			
			String sName = file.getName();
			FileInfo fileInfo = new FileInfo();
			fileInfo.setsName(sName);
			fileInfo.setlLong(file.length());
			fileInfo.setsTime(TimeUtil.toStr(file.lastModified()));
			fileInfo.setsPath(file.getPath().replaceAll("\\\\", "/").replace(targetRootDir, ""));
			//fileInfo.setsType(sName.substring(sName.lastIndexOf("."), sName.length()));
			
			list.add(fileInfo);
		}
		
		if (list.size() > 0) {
			String txt = JacksonShell.toJSONString(list);
			FileUtil.saveStr(String.format("%s/info.txt", dir), txt);
			
			folderInfo.setFileInfos(list);
			txt = JacksonShell.toJSONString(folderInfo);
			FileUtil.saveStr(String.format("%s/folderInfo.txt", dir), txt);
			
			return MsgEmity.success(folderInfo, "执行成功");
		}
		
		String txt = JacksonShell.toJSONString(folderInfo);
		FileUtil.saveStr(String.format("%s/folderInfo.txt", dir), txt);
		
		return MsgEmity.success(folderInfo, "执行完毕");
	}
	
	//---------------------------- 创建目录内的文件信息 结束 -------------------------//
	
	/**
	 * 上传文件
	 * @param dir
	 * @param file
	 * @return
	 */
	@Override
	public MsgEmity upFile(String dir, MultipartFile file) {
		if (null == dir || "".equals(dir.trim())) {
			return MsgEmity.err(8001, "请求存储的路径为空");
		}

		dir = dir.trim().replaceAll("\\\\", "/");
		File temp = new File(dir);
		if (temp.isDirectory() || temp.isFile()) {
			return MsgEmity.err(8002, "出于安全考虑,请求存储的路径不能是绝对路径");
		}
		
		String name = file.getOriginalFilename();
//		if (null == name || "".equals(name.trim())) {
//			name = file.getOriginalFilename();
//		} else if(!name.matches("[^/\\\\<>*?|\"]+\\.[^/\\\\<>*?|\"]+")) {
//			return MsgEmity.err(8003, "指定的文件名不合法");
//		}

		String savePath = String.format("%s/%s/%s", targetRootDir, dir, name.trim())
				.replaceAll("\\\\", "/").replaceAll("//", "/");
		
		File saveFile = new File(savePath);
		if (!saveFile.getParentFile().exists()) {
			saveFile.getParentFile().mkdirs();
		}
		
		try {
			file.transferTo(saveFile);
		} catch (Exception e) {
			Log.error("文件保存发生异常:", e.getMessage());
			return MsgEmity.err(8004, "文件保存发生异常:", e.getMessage());
		}
		
		if (!saveFile.exists()) {
			return MsgEmity.err(8005, "文件保存失败");
		}
		
		savePath = savePath.replace(targetRootDir, "");//去除根路径,以获得相对路径
		
		searchDir(saveFile.getParent(), false);//创建目录内的文件信息
		
		return new MsgEmity(true, "文件保存成功", savePath);
	}

	/**
	 * 删除文件
	 * @param path
	 * @return
	 */
	@Override
	public MsgEmity delFile(String path) {
		if (null == path) {
			return MsgEmity.err(8001, "文件参数不能为空");
		}
		
		String filePath = String.format("%s/%s", targetRootDir, path.trim()).replaceAll("//", "/");
		File file = new File(filePath);
		if (!file.exists()) {
			return MsgEmity.success(8999, "文件本身不存在");
		}
		
		if (!file.isFile()) {
			return MsgEmity.err(8002, "指定文件参数不是一个文件,不能删除");
		}
		
		boolean bl = file.delete();
		if (!bl) {
			return MsgEmity.err(8003, "删除失败,请检查文件是否在占用中");
		}
		
		searchDir(file.getParent(), false);//创建目录内的文件信息
		
		return MsgEmity.success(8999, "删除文件成功");
	}

	/**
	 * 删除文件夹
	 * @param dir
	 * @return
	 */
	@Override
	public MsgEmity delFolder(String dir) {
		if (null == dir) {
			return MsgEmity.err(8001, "指定文件夹参数缺失");
		}
		
		dir = dir.trim().replaceAll("\\\\", "/").replaceAll("//", "/");
		if ("".equals(dir) || "\\;/".contains(dir)) {
			return MsgEmity.err(8002, "不允许删除根路径");
		}
		
		String filePath = String.format("%s/%s", targetRootDir, dir).replaceAll("//", "/");
		File file = new File(filePath);
		if (!file.exists()) {
			return MsgEmity.success(8999, "文件夹本身不存在");
		}
		
		if (!file.isDirectory()) {
			return MsgEmity.err(8003, "指定文件夹参数不是一个目录,不能删除");
		}
		
		boolean bl = FileUtil.delDir(file);
		if (!bl) {
			return MsgEmity.err(8004, "删除失败,请检查文件夹是否在占用中");
		}
		
		return MsgEmity.success(8999, "删除文件夹成功");
	}

	//---------------------------- 查找文件夹信息 开始 -----------------------------//
	
	/**
	 * 查找文件夹信息
	 * @param dir
	 * @return
	 */
	@Override
	public MsgEmity findFolder(String dir) {
		if (null == dir) {
			return MsgEmity.err(8001, "指定文件夹参数缺失");
		}
		
		dir = dir.trim().replaceAll("\\\\", "/").replaceAll("//", "/");
		if ("".equals(dir) || "\\;/".contains(dir)) {
			return MsgEmity.err(8002, "不允许直接访问根路径");
		}
		
//		String filePath = String.format("%s/%s/folderInfo.txt", targetRootDir, dir).replaceAll("//", "/");
//		File file = new File(filePath);
//		if (!file.exists()) {
//			return MsgEmity.err(8999, "文件夹信息不存在");
//		}
//		
//		MsgEmity me = FileUtil.readFile(file);
//		if (!me.isSuccess()) {
//			return me;
//		}
//		
//		FileInfo fileInfo = JacksonShell.toJavaObject((String)me.getData(), FileInfo.class);
//		
//		return MsgEmity.success(fileInfo, "文件夹信息获取成功");

		String filePath = String.format("%s/%s", targetRootDir, dir).replaceAll("//", "/");
		File file = new File(filePath);
		if (!file.exists()) {
			return MsgEmity.err(8999, "文件夹信息不存在");
		}
		
		return folders(filePath);
	}
	
	private MsgEmity folders(String dir) {
		File folder = new File(dir);
		if (!folder.exists()) {
			return MsgEmity.err(8011, "目录不存在");
		}

		if (!folder.isDirectory()) {
			return MsgEmity.err(8012, "指定目录参数不是一个正确目录");
		}
		
		if (folder.listFiles().length < 1) {
			return MsgEmity.err(8013, "空目录");
		}

		List<FolderInfo> list = new ArrayList<>(folder.list().length);
		for (File file : folder.listFiles()) {
			if (!file.isDirectory()) {
				continue;
			}
			
			FolderInfo folderInfo = new FolderInfo();
			folderInfo.setsName(file.getName());
			folderInfo.setsTime(TimeUtil.toStr(file.lastModified()));
			folderInfo.setsPath(file.getPath().replaceAll("\\\\", "/").replace(targetRootDir, ""));

			list.add(folderInfo);
			
			MsgEmity me = folders(file.getPath());
			if (!me.isSuccess()) {
				continue;
			}
			
			folderInfo.setChilds(me.getData());
		}
		
		if (list.size() < 1) {
			return MsgEmity.err(8014, "没有子目录");
		}
		
		return MsgEmity.success(list, "执行完毕");
	}
	
//	/**
//	 * 读取文件信息
//	 * @param dir
//	 * @param list
//	 * @param isRecursion
//	 * @return
//	 */
//	private MsgEmity readFileInfo(String dir, List<FileInfo> list, boolean isRecursion) {
//		File folder = new File(dir);
//		if (!folder.exists()) {
//			return MsgEmity.err(8011, "目录不存在");
//		}
//		
//		if (!folder.isDirectory()) {
//			return MsgEmity.err(8012, "指定目录参数不是一个正确目录");
//		}
//		
//		for (File file : folder.listFiles()) {
//			if (file.isDirectory() && isRecursion) {
//				readFileInfo(file.getPath(), list, isRecursion);
//				continue;
//			}
//			
//			if (!file.getName().equalsIgnoreCase("info.txt")) {
//				continue;
//			}
//			
//			MsgEmity me = FileUtil.readFile(file);
//			if (!me.isSuccess()) {
//				continue;
//			}
//			
//			FileInfo fileInfo = JacksonShell.toJavaObject((String)me.getData(), FileInfo.class);
//			
//			list.add(fileInfo);
//		}
//		
//		return MsgEmity.success(list, "执行完毕");
//	}
	
	//---------------------------- 查找文件夹信息 结束 -----------------------------//

	/**
	 * 读取文件内容
	 * @param dir
	 * @param name
	 * @return
	 */
	@Override
	public MsgEmity readFile(String dir, String name) {
		if (null == name || "".equals(name.trim())) {
			return MsgEmity.err(8001, "请指定文件名");
		}
		
		if (null == dir) {
			dir = "";
		}
		
		String filePath = String.format("%s/%s/%s", targetRootDir, dir.trim(), name.trim()).replaceAll("//", "/");
		File file = new File(filePath);
		if (!file.exists()) {
			return MsgEmity.err(8002, "文件不存在");
		}
		
		return FileUtil.read(filePath);
	}

	/**
	 * 保存内容到文件
	 * @param dir
	 * @param name
	 * @param sContent
	 * @return
	 */
	@Override
	public MsgEmity saveFile(String dir, String name, String sContent) {
		if (null == name || "".equals(name.trim())) {
			return MsgEmity.err(8001, "请指定文件名");
		}
		
		if (null == sContent) {
			return MsgEmity.err(8002, "文件内容缺失");
		}
		
		if (null == dir) {
			dir = "";
		}
		
		String filePath = String.format("%s/%s/%s", targetRootDir, dir.trim(), name.trim()).replaceAll("//", "/");
		
		boolean bl = FileUtil.saveStr(filePath, sContent);
		if (!bl) {
			return MsgEmity.err(8003, "保存文件失败");
		}
		
		searchDir(dir, false);//创建目录内的文件信息
		
		return MsgEmity.success("保存文件成功");
	}

	/**
	 * 资源管理器
	 * @param dir
	 * @return
	 */
	@Override
	public MsgEmity explorer(String dir) {
		if (null == dir) {
			dir = "";
		}

		dir = dir.trim().replaceAll("\\\\", "/").replaceAll("//", "/");
		String filePath = String.format("%s/%s", targetRootDir, dir.trim());
		File folder = new File(filePath);
		if (!folder.exists()) {
			return MsgEmity.err(8999, "文件夹信息不存在");
		}
		
		ExplorerInfo result = new ExplorerInfo();//当前
		result.setsName(folder.getName());
		result.setiDir(folder.isDirectory() ? 1 : 0);
		result.setlLong(folder.length());
		result.setsTime(TimeUtil.toStr(folder.lastModified()));
		result.setsPath(folder.getPath().replaceAll("\\\\", "/").replace(targetRootDir, ""));
		result.setsPaterPath(folder.getParent().replaceAll("\\\\", "/").replace(targetRootDir, ""));
		result.setiChildsCount(1);

		List<ExplorerInfo> listDir = new ArrayList<>(10);
		List<ExplorerInfo> listFile = new ArrayList<>(10);
		for (File file : folder.listFiles()) {
			String sName = file.getName();
			ExplorerInfo explorerInfo = new ExplorerInfo();
			explorerInfo.setsName(sName);
			explorerInfo.setiDir(file.isDirectory() ? 1 : 0);
			explorerInfo.setlLong(file.length());
			explorerInfo.setsTime(TimeUtil.toStr(file.lastModified()));
			explorerInfo.setsPath(file.getPath().replaceAll("\\\\", "/").replace(targetRootDir, ""));
			explorerInfo.setsPaterPath(folder.getParent().replaceAll("\\\\", "/").replace(targetRootDir, ""));
			explorerInfo.setiChildsCount(file.isDirectory() ? file.listFiles().length : -1);
			
			if (sName.contains(".")) {
				explorerInfo.setsType(sName.substring(sName.lastIndexOf("."), sName.length()));
			}

			if (file.isDirectory()) {
				listDir.add(explorerInfo);
			} else {
				listFile.add(explorerInfo);
			}
		}

		List<ExplorerInfo> list = new ArrayList<>(listDir.size() + listFile.size());
		list.addAll(listDir);
		list.addAll(listFile);
		result.setChilds(list);
		
		return MsgEmity.success(result, "查询结束");
	}
	
	/**
	 * 添加文件夹
	 * @param dir
	 * @param name
	 * @return
	 */
	@Override
	public MsgEmity addFolder(String dir, String name) {
		if (null == dir || "".equals(dir.trim())) {
			return MsgEmity.err(8001, "请求存储的路径为空");
		}

		dir = dir.trim().replaceAll("\\\\", "/");
		File temp = new File(dir);
		if (temp.isDirectory() || temp.isFile()) {
			return MsgEmity.err(8002, "出于安全考虑,请求存储的路径不能是绝对路径");
		}

		String path = String.format("%s/%s/%s", targetRootDir, dir, name.trim())
				.replaceAll("\\\\", "/").replaceAll("//", "/");
		
		File file = new File(path);
		if (file.exists()) {
			return MsgEmity.err(8003, "存在同名文件");
		}
		
		file.mkdirs();
		
		return MsgEmity.success(8999, "创建成功");
	}
	
	/**
	 * 初始化页面
	 * @param dir 上级目录
	 * @param name 文件夹名
	 * @param iOverlap 是否直接覆盖;1:true
	 * @return
	 */
	@Override
	public MsgEmity htmlInit(String dir, String name, Integer iOverlap) {
		String source = String.format("%s/templet/Retrospect.html", System.getProperty("user.dir"));
		String target = String.format("%s/%s/%s/source.html", targetRootDir, dir, name.trim());
		
		return FileUtil.copyFile(iOverlap != 1 ? false : true, source, target);
	}
	
	/**
	 * 保存页面
	 * @param sPath 文件路径(相对路径)
	 * @param sContent 内容
	 * @return
	 */
	@Override
	public MsgEmity htmlSave(String sPath, String sContent) {
		if (null == sPath || "".equals(sPath.trim())) {
			return MsgEmity.err(8001, "请求存储的路径为空");
		}
		
		sPath = String.format("%s/%s", targetRootDir, sPath.trim());
		
		if (!FileUtil.saveStr(sPath, sContent)) {
			return MsgEmity.err(8002, "保存失败");
		}
		
		return MsgEmity.success("保存成功");
	}

	/**
	 * 创建页面
	 * @param path 相对路径
	 * @return
	 */
	@Override
	public MsgEmity createHtml(String sPath) {
		if (null == sPath || "".equals(sPath.trim())) {
			return MsgEmity.err(8001, "请求存储的路径为空");
		}
		
		String source = String.format("%s/templet/Retrospect.html", System.getProperty("user.dir"));
		String target = String.format("%s/%s/source.html", targetRootDir, sPath.trim());
		
		MsgEmity me = FileUtil.copyFile(true, source, target);
		if (!me.isSuccess()) {
			return me;
		}
		
		//--加入产品信息--//
//		String txt = 
		
		
		
		
		return MsgEmity.success("完成");
	}
	
}
